home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
(A)P
/
(A)P1.ADF
/
life
/
blit.c
next >
Wrap
C/C++ Source or Header
|
1987-05-25
|
4KB
|
143 lines
/*
* This include file includes the defines for all the blitter functions.
* It only allows use of the `blit' operations; for area fills or line
* drawing, it will need to be extended.
*
* Information gleaned from the Hardware Reference Manual.
*/
#define BLTADD (0xdff040L)
/*
* This structure contains everything we need to know.
* Do not do a structure copy into this! Instead, assign
* each field. The last field assigned must be bltsize; that
* starts up the blitter. Also note that all of these are
* write only, and you can't read them.
*/
struct bltstruct {
short con0 ;
short con1 ;
short afwm ;
short alwm ;
short *csource, *bsource, *asource, *dsource ;
short bltsize ;
short dmy1, dmy2, dmy3 ;
short cmod, bmod, amod, dmod ;
} *blitter = BLTADD ;
/*
* We need an array which tells what to use for all 256 possible operations.
*/
#define USEA (0x8)
#define USEB (0x4)
#define USEC (0x2)
#define USED (0x1)
char touse[256] ;
char fwma[16] ;
char lwma[16] ;
/*
* Call initblitdata() once on startup before you ever call blit.
*/
initblitdata() {
register int i ;
register int s ;
for (i=0; i<256; i++) {
s = USED ;
if ((i >> 4) != (i & 15))
s += USEA ;
if (((i >> 2) & 51) != (i & 51))
s += USEB ;
if (((i >> 1) & 85) != (i & 85))
s += USEC ;
touse[i] = s ;
}
s = 0xffff ;
for (i=0; i<16; i++) {
fwma[i] = s ;
s = (s >> 1) & ~0x8000 ;
lwma[i] = 0xffff - s ;
}
}
/*
* This is the major user interface. Takes addresses and offsets for
* all four locations, a modulo and sizes, and a function.
* Assumes the modulos for all sources and destination are the same.
* You might want to add some arguments or delete some.
*
* All arguments are in pixels (except the addresses and function.)
*
* Before you call this routine, call OwnBlitter(); after you have
* called it as many times as you need, call DisownBlitter(). Remember
* that you cannot do any printf's or anything else which requires the
* blitter when you own the blitter, so be careful with the debug code.
* The machine will lock but will not crash.
*/
blit(aaddress, ax, ay,
baddress, bx, by,
caddress, cx, cy,
daddress, dx, dy,
modulo, xsize, ysize, function)
short *aaddress, *baddress, *caddress, *daddress ;
int ax, ay, bx, by, cx, cy, dx, dy, modulo,
xsize, ysize, function ;
{
short *t ;
/*
* Divide the modulo by 16 because we need words.
*/
modulo >>= 4 ;
/*
* Wait for the blitter to finish whatever it needs to do.
*/
WaitBlit() ;
/*
* Calculate the real addresses for d and c.
*/
blitter->dsource = daddress + modulo * dy + (dx >> 4) ;
blitter->csource = caddress + modulo * cy + (cx >> 4) ;
/*
* Mask out the low order bits of dx; add these to the xsize. (The
* first bits will be masked using the first word mask.)
*/
dx &= 15 ;
xsize += dx ;
blitter->afwm = fwma[dx] ;
blitter->alwm = lwma[(xsize - 1) & 15] ;
/*
* Now calculate the shifts for the a and b operands. The barrel
* shifter counts appear to be to the left instead of the more
* intuitive to the right. Note that I take dx into account.
*/
t = aaddress + modulo * ay + (ax >> 4) ;
ax = dx - (ax & 15) ;
if (ax < 0) {
t++ ;
ax += 16 ;
}
blitter->asource = t ;
t = baddress + modulo * by + (bx >> 4) ;
bx = dx - (bx & 15) ;
if (bx < 0) {
t++ ;
bx += 16 ;
}
blitter->bsource = t ;
/*
* Now calculate the two control words. If you want to do
* the addresses in reverse order, set the appropriate bit in con1.
*/
blitter->con0 = (ax << 12) + (touse[function] << 8) + function ;
blitter->con1 = (bx << 12) ;
/*
* Calculate the final total xsize in words, and the modulos. The
* modulos are in bytes when written from the 68000.
*/
xsize = (xsize + 15) >> 4 ;
blitter->amod = blitter->bmod = blitter->cmod = blitter->dmod =
2 * (modulo - xsize) ;
/*
* This last assignment starts up the blitter.
*/
blitter->bltsize = (ysize << 6) + xsize ;
}